#!/usr/bin/python

import subprocess
import sys
from datetime import datetime, timedelta


def measure_elapsed_times(executable, nmin, nmax, repetitions):
    times = []
    while nmin <= nmax:
        total = timedelta(seconds=0)
        for i in range(repetitions):
            command = "{0} {1} > /dev/null".format(executable, nmin)
            start = datetime.now()
            subprocess.call(
                command,
                stderr=subprocess.STDOUT,
                shell=True)
            total += datetime.now() - start
        average = total / repetitions
        seconds = average.total_seconds()
        spd = seconds / nmin
        times.append((nmin, seconds, spd))
        print("{0} {1}".format(nmin, seconds))
        nmin += 500
    return times

# Same thing using /usr/bin/time

# out = subprocess.check_output(
#     "/usr/bin/time ./pi {0} > /dev/null".format(nmin),
#     stderr=subprocess.STDOUT,
#     shell=True)
# time = float(str(out, 'utf-8').split('elapsed')[0].split(' ')[-1])
# total += time


def generate_figures(data):
    try:
        from matplotlib import pyplot
    except:
        print("matplotlib.pyplot required to generate the figures")
    else:
        decimals = [i[0] for i in data]
        seconds = [i[1] for i in data]
        spd = [i[2] for i in data]
        pyplot.plot(decimals, spd)
        pyplot.xlabel('Number of decimals')
        pyplot.ylabel('Elapsed time (s) / Number of decimals')
        pyplot.savefig('time_per_decimal_decimals.png')
        pyplot.plot(decimals, seconds)
        pyplot.xlabel('Number of decimals')
        pyplot.ylabel('Elapsed time (s)')
        pyplot.savefig('elapsed_time_decimals.png')


if not 3 < len(sys.argv) < 6:
    print("usage:\n{0} 'exec' nmin nmax [repetitions]".format(sys.argv[0]))
    print("adds one argument to 'executable' (the number of decimal places)")
    print("does 5 repetitions by default")
else:
    try:
        executable = sys.argv[1]
        nmin = int(sys.argv[2])
        nmax = int(sys.argv[3])
        repetitions = int(sys.argv[4]) if len(sys.argv) > 4 else 5
    except ValueError:
        print("nmin, nmax  and repetitions must be numbers")
    else:
        if nmin > nmax:
            print("nmin must be less than nmax")
        elif nmin < 1 or repetitions < 1:
            print("nmin and repetitions must be positive")
        else:
            times = measure_elapsed_times(executable, nmin, nmax, repetitions)
            generate_figures(times)
